package csc.traning.wpsj.servlet;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import csc.traning.wpsj.dao.User;

/**
 * Servlet implementation class ZipDownloadServlet
 *  * @author hdang20
 */
public class ZipDownloadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public static final String FILE_SEPARATOR = System.getProperty("file.separator");
	private static String DESTINATION_DIR_PATH ="";
	private File destinationDir;
	
	/**
     * @see HttpServlet#HttpServlet()
     */
    public ZipDownloadServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			HttpSession session = request.getSession();
			User user = (User)session.getAttribute("user");
			if(user == null){
				throw new ServletException("Required to login");
	        }
	        //String basePath = getServletContext().getRealPath(new StringBuffer("users/").append(user.getUserName()).append("/upload-folder").toString());
	        DESTINATION_DIR_PATH = getServletContext().getRealPath(new StringBuffer("users/").append(user.getUserName()).append("/upload-folder").toString());;
			String[] filenames = request.getParameterValues("filename");
			
			String currentFolder = request.getParameter("currentFolder");
			
			if(currentFolder!=null && !currentFolder.equals("")){
				 //String[] folers =  currentFolder.split("_");
	             String currentFolderPath = "";
				 //for (String folder : folers) {
	           	 currentFolderPath = new StringBuffer(currentFolderPath).append("/").append(currentFolder).toString();
	             //}
				 DESTINATION_DIR_PATH = DESTINATION_DIR_PATH + "/" + currentFolderPath;
			}
			
			String path = DESTINATION_DIR_PATH;
			File directory = new File(path);
			File[] sourceFiles = null;
			if(filenames != null && filenames.length > 0){
				sourceFiles = new File[filenames.length];
				for (int i = 0; i < sourceFiles.length; i++) {
					sourceFiles[i] =  new File(path + "/" + filenames[i]);
				}
			}
			byte[] zip = null;
			if(sourceFiles != null && sourceFiles.length > 0)
				zip = zipFiles(sourceFiles, path);
			else
				zip = zipFiles(directory.listFiles(), path);
			ServletOutputStream sos = response.getOutputStream();
			
			// Let Browser understand the zip file
			response.setContentType("application/zip");
			response.setHeader("Content-Disposition", "attachment; filename=\"downloads.zip\"");
			sos.write(zip);
			sos.flush();
			
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	
	
	/**
	* Compress the given directory with all its files.
	 * @throws Exception 
	*/
	private byte[] zipFiles(File[] files, String baseFolderName) throws Exception {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ZipOutputStream zos = new ZipOutputStream(baos);
		
		for (File file : files) {
			addFolder(zos, file.getAbsolutePath(), baseFolderName);
		}
		
		/*byte bytes[] = new byte[2048];
		for (File f : files) {
			FileInputStream fis = new FileInputStream(f.getAbsolutePath());
			BufferedInputStream bis = new BufferedInputStream(fis);
			zos.putNextEntry(new ZipEntry(f.getName()));
			int bytesRead;
			while ((bytesRead = bis.read(bytes)) != -1) {
				zos.write(bytes, 0, bytesRead);
			}
			zos.closeEntry();
			bis.close();
			fis.close();
		}*/
		zos.flush();
		baos.flush();
		zos.close();
		baos.close();
		 
		return baos.toByteArray();
	}
	
	private static void addFolder(ZipOutputStream zos,String folderName,String baseFolderName)throws Exception{
		File f = new File(folderName);
		if(f.exists()){
			if(f.isDirectory()){
				File f2[] = f.listFiles();
				for(int i=0;i<f2.length;i++){
					addFolder(zos,f2[i].getAbsolutePath(),baseFolderName);	
				}
			}else{
				//add file
				//extract the relative name for entry purpose
				String entryName = folderName.substring(baseFolderName.length()+1,folderName.length());
				System.out.print("Adding entry " + entryName + "...");
				ZipEntry ze= new ZipEntry(entryName);
				zos.putNextEntry(ze);
				FileInputStream in = new FileInputStream(folderName);
				int len;
				byte buffer[] = new byte[1024];
				while ((len = in.read(buffer)) > 0) {
					zos.write(buffer, 0, len);
				}
				in.close();
				zos.closeEntry();
				System.out.println("OK!");

			}
		}else{
			System.out.println("File or directory not found " + folderName);
		}

	}
	
	
	
	
    
    
}
